# -*- coding: utf-8 -*-
from datetime import datetime
from decimal import Decimal
from django.core import validators
from django.db import models

class Student(models.Model):
    group = models.ForeignKey('StudentGroup', verbose_name="Группа студентов")
    user = models.ForeignKey('auth.User', verbose_name="Пользователь")
    stud_classes = models.ManyToManyField('StudentClass', verbose_name="Категория", blank=True)
    record_book = models.CharField('Номер зачётной книжки', max_length=10)
    grade_level = models.PositiveIntegerField('Год обучения', max_length=6, validators=[validators.MaxValueValidator(10)])
    enter_date = models.DateField('Дата поступления')
    
    class Meta:
        verbose_name = u"Студент"
        verbose_name_plural = u"Студенты"
        ordering = ['user']
        permissions = (
            ("view_student", u"Can view %s" % verbose_name),
            ("list_student", u"Can list %s" % verbose_name),
            ("students_by_group", u"Can view list of students by group"),
        )
    
    def __unicode__(self):
        return self.user.get_full_name()

class StudentClass(models.Model):
    name = models.CharField('Название', max_length=128)
    coefficient = models.DecimalField('Коэффициент', max_digits=19, decimal_places=2, validators=[validators.MinValueValidator(Decimal('0.0'))])
    payment = models.DecimalField('Сумма материальной помощи', max_digits=19, decimal_places=2, validators=[validators.MinValueValidator(Decimal('0.0'))])
    restriction = models.BooleanField('Запрещающая категория')
    
    class Meta:
        verbose_name = u"Категория студента"
        verbose_name_plural = u"Категории студентов"
        ordering = ['name']
        permissions = (
            ("view_studentclass", u"Can view %s" % verbose_name),
            ("list_studentclass", u"Can list %s" % verbose_name),
        )
    
    def __unicode__(self):
        return self.name

class StudentGroup(models.Model):
    speciality = models.ForeignKey('Speciality', verbose_name="Специальность")
    name = models.CharField('Название', max_length=64)
    enter_date = models.DateField('Дата формирования')
    
    class Meta:
        verbose_name = u"Группа студентов"
        verbose_name_plural = u"Группы студентов"
        ordering = ['name']
        permissions = (
            ("view_studentgroup", u"Can view %s" % verbose_name),
            ("list_studentgroup", u"Can list %s" % verbose_name),
        )
    
    def __unicode__(self):
        return self.name

class Speciality(models.Model):
    faculty = models.ForeignKey('Faculty', verbose_name="Факультет")
    name = models.CharField('Название', max_length=128)
    
    class Meta:
        verbose_name = u"Специальность"
        verbose_name_plural = u"Специальности"
        ordering = ['name']
        permissions = (
            ("view_speciality", u"Can view %s" % verbose_name),
            ("list_speciality", u"Can list %s" % verbose_name),
        )
    
    def __unicode__(self):
        return self.name

class Faculty(models.Model):
    name = models.CharField('Название', max_length=128)
    
    class Meta:
        verbose_name = u"Факультет"
        verbose_name_plural = u"Факультеты"
        ordering = ['name']
        permissions = (
            ("view_faculty", u"Can view %s" % verbose_name),
            ("list_faculty", u"Can list %s" % verbose_name),
        )
    
    def __unicode__(self):
        return self.name

class Committee(models.Model):
    faculty = models.ForeignKey('Faculty', verbose_name="Факультет", blank=True, null=True)
    user = models.ForeignKey('auth.User', verbose_name="Пользователь")
    
    class Meta:
        verbose_name = u"Член комиссии"
        verbose_name_plural = u"Члены комиссии"
        ordering = ['faculty']
        permissions = (
            ("view_committee", u"Can view %s" % verbose_name),
            ("list_committee", u"Can list %s" % verbose_name),
        )
    
    def __unicode__(self):
        return unicode(self.user)

class Session(models.Model):
    speciality = models.ForeignKey('Speciality', verbose_name="Специальность")
    disciplines = models.ManyToManyField('Discipline', verbose_name="Дисциплины")
    number = models.PositiveIntegerField('Номер', validators=[validators.MaxValueValidator(20)])
    start_date = models.DateField('Дата начала')
    end_date = models.DateField('Дата завершения')
    
    class Meta:
        verbose_name = u"Сессия"
        verbose_name_plural = u"Сессии"
        ordering = ['start_date']
        permissions = (
            ("view_session", u"Can view %s" % verbose_name),
            ("list_session", u"Can list %s" % verbose_name),
            ("result_session", u"Can view session results by group"),
        )
    
    def __unicode__(self):
        return unicode(self.speciality) + u" # " + unicode(self.number)

class Examination(models.Model):
    session = models.ForeignKey('Session', verbose_name="Сессия")
    discipline = models.ForeignKey('Discipline', verbose_name="Дисциплина")
    group = models.ForeignKey('StudentGroup', verbose_name="Группа студентов")
    date = models.DateField('Дата')
    
    class Meta:
        verbose_name = u"Экзамен"
        verbose_name_plural = u"Экзамены"
        ordering = ['date']
        permissions = (
            ("view_examination", u"Can view %s" % verbose_name),
            ("list_examination", u"Can list %s" % verbose_name),
        )
    
    def __unicode__(self):
        return unicode(self.discipline) + u" | " + unicode(self.date)

class Mark(models.Model):
    MARK_CHOICES = (
        (2, u'Неудовлетворительно'),
        (3, u'Удовлетворительно'),
        (4, u'Хорошо'),
        (5, u'Отлично'),
    )
    examination = models.ForeignKey('Examination', verbose_name="Экзамен")
    student = models.ForeignKey('Student', verbose_name="Студент")
    grade = models.IntegerField('Результат', choices=MARK_CHOICES)
    
    class Meta:
        verbose_name = u"Оценка"
        verbose_name_plural = u"Оценки"
        ordering = ['examination', 'student']
        permissions = (
            ("view_mark", u"Can view %s" % verbose_name),
            ("list_mark", u"Can list %s" % verbose_name),
        )
        unique_together = (
            ("student", "examination")
        )
    
    def __unicode__(self):
        return unicode(self.student) + u": " + unicode(self.grade)

class Discipline(models.Model):
    name = models.CharField('Название', max_length=256)
    
    class Meta:
        verbose_name = u"Дисциплина"
        verbose_name_plural = u"Дисциплины"
        ordering = ['name']
        permissions = (
            ("view_discipline", u"Can view %s" % verbose_name),
            ("list_discipline", u"Can list %s" % verbose_name),
        )
    
    def __unicode__(self):
        return self.name

class Scholarship(models.Model):
    session = models.ForeignKey('Session', verbose_name="Сессия")
    student = models.ForeignKey('Student', verbose_name="Студент")
    cash = models.ForeignKey('Cash', verbose_name="Выплата")
    
    class Meta:
        verbose_name = u"Стипендия"
        verbose_name_plural = u"Стипендии"
        ordering = ['session']
        permissions = (
            ("view_scholarship", u"Can view %s" % verbose_name),
            ("list_scholarship", u"Can list %s" % verbose_name),
            ("scholarship_by_semester", u"Can view list of scholarships by semester"),
            ("distribute_scholarship", u"Can distribute %s" % verbose_name),
        )
    
    def __unicode__(self):
        return unicode(self.student) + u": " + unicode(self.cash)

class SSF(models.Model):
    money = models.DecimalField('Сумма', max_digits=19, decimal_places=2)
    date = models.DateTimeField('Дата')
    
    class Meta:
        verbose_name = u"Фонд социальной защиты"
        verbose_name_plural = u"История Фонда социальной защиты"
        ordering = ['date']
        permissions = (
            ("view_ssf", u"Can view %s" % verbose_name),
            ("list_ssf", u"Can list %s" % verbose_name),
        )
    
    def __unicode__(self):
        return unicode(self.date) + u": " + unicode(self.money)

class SSFDiff(models.Model):
    date = models.DateField('Дата')
    balance = models.DecimalField('Баланс', max_digits=19, decimal_places=2)
    
    class Meta:
        verbose_name = u"Изменение Фонда социальной защиты"
        verbose_name_plural = u"Изменения Фонда социальной защиты"
        ordering = ['date']
        permissions = (
            ("view_ssfdiff", u"Can view %s" % verbose_name),
            ("list_ssfdiff", u"Can list %s" % verbose_name),
        )
    
    def __unicode__(self):
        return unicode(self.balance)

class Cash(models.Model):
    ssf_diff = models.ForeignKey('SSFDiff', null=True, blank=True, verbose_name="Изменение фонда")
    payment = models.DecimalField('Сумма', max_digits=19, decimal_places=2, validators=[validators.MinValueValidator(Decimal('0.0'))])
    
    class Meta:
        verbose_name = u"Выплата"
        verbose_name_plural = u"Выплаты"
        ordering = ['ssf_diff']
        permissions = (
            ("view_cash", u"Can view %s" % verbose_name),
            ("list_cash", u"Can list %s" % verbose_name),
        )
    
    def __unicode__(self):
        return unicode(self.payment)

class Welfare(models.Model):
    student = models.ForeignKey('Student', verbose_name="Студент")
    cash = models.ForeignKey('Cash', verbose_name="Выплата")
    date = models.DateField('Дата')
    welfare_request = models.ForeignKey('WelfareRequest', blank=True, null=True)
    
    class Meta:
        verbose_name = u"Социальное пособие"
        verbose_name_plural = u"Социальные пособия"
        ordering = ['date']
        permissions = (
            ("view_welfare", u"Can view %s" % verbose_name),
            ("list_welfare", u"Can list %s" % verbose_name),
            ("distribute_welfare", u"Can distribute %s" % verbose_name),
        )
    
    def __unicode__(self):
        return unicode(self.student) + u" | " + unicode(self.date)

class WelfareRequest(models.Model):
    student = models.ForeignKey('Student', verbose_name="Студент")
    date = models.DateField('Дата', default=datetime.now)
    cash = models.DecimalField('Сумма', max_digits=19, decimal_places=2, validators=[validators.MinValueValidator(Decimal('0.0'))])
    description = models.TextField('Описание')
    
    class Meta:
        verbose_name = u"Запрос на материальную помощь"
        verbose_name_plural = u"Запросы на материальную помощь"
        ordering = ['date']
        permissions = (
            ("view_welfarerequest", u"Can view %s" % verbose_name),
            ("list_welfarerequest", u"Can list %s" % verbose_name),
            ("send_request", u"Can send %s" % verbose_name),
        )
    
    def __unicode__(self):
        return unicode(self.student) + ": " + unicode(self.date)

class MinWage(models.Model):
    money = models.DecimalField('Сумма', max_digits=19, decimal_places=2, validators=[validators.MinValueValidator(Decimal('0.0'))])
    date = models.DateField('Дата')
    
    class Meta:
        verbose_name = u"Минимальный размер оплаты труда"
        verbose_name_plural = u"Минимальные размеры оплаты труда"
        ordering = ['date']
        permissions = (
            ("view_minwage", u"Can view %s" % verbose_name),
            ("list_minwage", u"Can list %s" % verbose_name),
        )
    
    def __unicode__(self):
        return unicode(self.money) + u": " + unicode(self.date)

def get_by_raw_SQL(clazz, query, params):
    if not issubclass(clazz, models.Model):
        raise ValueError("clazz must be subclass of django.db.models.Model")
    return list(clazz.objects.raw(query, params))
